<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

<script>
// ES5类与继承
// 在JS中没有类！！！
// 类 -> 构造函数

function Cat(n,c,a){
    // this -> Cat的实例对象
    this.name = n;
    this.color = c;
    this.age = a;
    this.say = function (){
        console.log( '卖萌~' );
    }
    this.type = 'animal';
    // return this; 默认返回
    // return {a:123};
}
Cat.hehe = '呵呵';// 静态属性
Cat.haha = function (){// 静态方法
    console.log( '哈哈' );
}
Cat.prototype.type = 'animal';
Cat.prototype.skill = function (){
    console.log( '抓老鼠' );
}
var cat1 = new Cat('小白','black',2);
var cat2 = new Cat('小黑','white',3);
console.log( cat1 );
console.log( cat2 );
console.log( cat1.skill );
console.log( cat1.abc );

// __proto__的主要作用是，维护原型链
// 查找过程：
// 1.查找cat1自身
// 2.查找cat1.__proto__ => {Cat.prototype}
// 3.查找cat1.__proto__.__proto__ => Cat.prototype.__proto__ => Object.prototype
// 4.查找cat1.__proto__.__proto__.__proto__ => Object.prototype.__proto__ => null
// cat1 -> Cat.prototype -> Object.prototype -> null

// 继承 -> 类之间的关系

// 需求1：Dog的实例对象也有name age color say等属性
// 需求2：Dog的实例对象也也有抓老鼠的技能

// 构造函数继承（对象冒充继承）
// 原理：在子类中调用父类的构造函数并改变this指向
function Dog(f,n,c,a){
    // this -> Dog的实例对象
    this.food = f;
    Cat.call(this,n,c,a);// 构造函数继承（对象冒充继承）
}
// 原型继承
// 原理：改变原型指向
// Dog.prototype = new Cat();// 如果Cat返回一个自定义对象，则继承失败
// dog1 -> Dog.prototype -> Cat实例 -> Cat.prototype -> Object.prototype -> null

// Dog.prototype = Cat.prototype;
// dog1 -> Dog.prototype -> Cat.prototype -> Object.prototype -> null

Dog.prototype = Object.create(Cat.prototype);// obj1
// dog1 -> Dog.prototype -> obj1 -> Cat.prototype -> Object.prototype -> null

var dog1 = new Dog('shi','大黄','yellow',3);
console.log( dog1 );
console.log( dog1.food );
console.log( dog1.name );
console.log( dog1.color );
console.log( dog1.age );
dog1.say();
console.log( dog1.skill );// undefined

// 查找过程：
// 1.查找dog1自身
// 2.查找dog1.__proto__ => Dog.prototype
// 3.查找dog1.__proto__.__proto__ => Dog.prototype.__proto__ => Object.prototype
// 4.查找dog1.__proto__.__proto__.__proto__ => Object.prototype.__proto__ => null
// 未继承之前：dog1 -> Dog.prototype -> Object.prototype -> null

</script>
</body>
</html>